import gdata.calendar.service as gCalService
import gdata.calendar
import gdata.service
import gdata
import tasklist
import task
import atom
import datetime


class GoogleTaskEngine:

    tasks_calendar_name = 'gTaskLet'

    def __init__(self, user, pw):
        self.username = user
        self.password = pw
        self.tasklist = tasklist.TaskList()
        self.tasksDate = datetime.date(1970, 1, 2)
        self.dateRange = \
            {'start': self.tasksDate - datetime.timedelta(1), #datetime.date
             'stop': self.tasksDate + datetime.timedelta(1) } #datetime.date
    
    def login(self):
        self.service = gCalService.CalendarService()
        self.service.email = self.username
        self.service.password = self.password
        self.service.source = 'gTaskLet'
        # TODO: add try: except: for captcha instances
        self.service.ProgrammaticLogin()
    
    def confirmLogin(self):
        if not hasattr(self,'service'):
            raise Exception('Not logged in to service')
    
    def downloadTaskList(self):
        self.confirmLogin()
        try:
            eventlist = self.getTaskEvents(str(self.dateRange['start']),
                                            str(self.dateRange['stop']))
            for event in eventlist:
                self.parseEvent(event)
        except Exception as ex:
            print ex
        
    def getTaskEvents(self, start_date, end_date):
        id = self.getTCalendar().id.text.split('/').pop().replace('%40','@')
        query = gCalService.CalendarEventQuery(id,'private','full')
        query.start_min = start_date
        query.start_max = end_date
        return self.service.CalendarQuery(query).entry
    
    def parseEvent( self, event ):
        t = task.Task( content=event.title.text )
        t.checkDone()
        self.tasklist.append(t)
    
    def getTCalendar(self):
        self.confirmLogin()
        tcalendar = None
        for cal in self.service.GetOwnCalendarsFeed().entry:
            if self.tasks_calendar_name == cal.title.text:
                tcalendar = cal
        
        if None == tcalendar: raise Exception('No tasks on account')
        
        return tcalendar
        
    def uploadTaskList(self):
        #   For now I'm using a very bad practice here:
        #   I'm deleting all the older tasks before uploading the new ones.
        #   In the future this should first upload the new list and only then
        #   delete the old one (if not just change the old calendar...)
        
        self.confirmLogin()
        
        #delete old calendar
        if not self.service.Delete( self.getTCalendar().GetEditLink().href ):
            raise Exception('Can\'t delete old calendar');
        
        #create new calendar
        newTCal = self.createTaskCalendar()
        batchHref = self.getBatchHref(newTCal)

        # create batch feed
        batchFeed = gdata.calendar.CalendarEventFeed()

        #create events for new calendar
        for task in self.tasklist:
            tEvent = self.createTaskEvent(task)
            batchFeed.AddInsert(entry=tEvent)

        #submit batch
        responseFeed = self.service.ExecuteBatch(batchFeed, batchHref)
        
    
    
    def createTaskCalendar(self):
        self.confirmLogin()
        
        #create the new calendar object
        tcalendar = gdata.calendar.CalendarListEntry()
        tcalendar.title = atom.Title(text=self.tasks_calendar_name)
        tcalendar.summary = atom.Summary(text='This calendar contains tasks for the gtasklet applet')
        tcalendar.color = gdata.calendar.Color(value='#A32929')
        tcalendar.hidden = gdata.calendar.Hidden(value='true')
        
        return self.service.InsertCalendar(new_calendar=tcalendar)



    def createTaskEvent(self, task):
        event = gdata.calendar.CalendarEventEntry()
        event.content = atom.Content( text=task.content + 
                   ({True:task.doneString, False:''}[task.ticked]) +
                   ' ' + str(self.tasksDate) )
        event.quick_add = gdata.calendar.QuickAdd(value='true')
        return event


    def getBatchHref(self, calListEntry):
        self.confirmLogin()
        calId = calListEntry.GetEditLink().href.split('/').pop().replace('%40','@')
        feed = self.service.GetCalendarEventFeed(uri='/calendar/feeds/'+calId+'/private/full')
        return feed.GetBatchLink().href

